import { Promise } from 'es6-promise';
import { Collection, ObjectID } from "mongodb";

import * as utils from '../core/utils';
import {AuditLog} from "../core/types";
import { Magics } from "../core/magics";
import {MongoColls} from "../config/mongo";
import {CursorType} from "../core/defines";
import { BaseModel } from "../core/base.model";
import {
    InsertParam,
    FindOneParam,
    FindParam,
    CountParam,
    UpdateParam,
    AggregateParam
} from '../core/params';
import {ErrCode} from "../core/error.code";

export enum ShopStatus {
    CREATE  = 1, //已创建
    OPENING = 2, //运营中
    STAGE   = 3, //暂存，撤销
    OFFLINE = 4, //下线
}

export enum ShopLevel {
    BRONZE   = 1,  //铜牌
    SILVER   = 2,  //银牌
    GOLD     = 3,  //金牌
    PLATINUM = 4,  //白金
    DIOMAND  = 5,  //钻石
}

export declare interface ShopInfo {
    name?: string,
    phone?: string,
    telephone?: string,
    level?: ShopLevel,
    introduction?: string,
    sid?: string,
    qrcode?: string,
    portrait?: string,
}

export declare interface ShopOwner {
    id: ObjectID,
    name: string,
    phone: string,
}

export declare interface Shop {
    _id?: ObjectID,
    info?: ShopInfo,
    owner?: ShopOwner,
    status?: ShopStatus,
    time?: Date,
}


export declare interface ShopFilter {
    _id?: ObjectID,
    name?: string,
    sid?: string,
}

export default class ShopModel extends BaseModel {
    constructor(coll: Collection) {
        super(coll);
    }

    name() { return 'ShopModel'; }

    checkExist(filter: ShopFilter, project?: Object): Promise<Shop> {
        return this.findOne(new FindOneParam(filter, project));
    }

    getShopInfo(filter: ShopFilter): Promise<Shop> {
        let lookup = {
            from: MongoColls.USER,
            localField: "owner_id",
            foreignField: "_id",
            as: "user"
        };
        let options = new AggregateParam();
        options.push(CursorType.MATCH, filter);
        options.push(CursorType.LOOKUP, lookup);
        return this.aggregate(options);
    }

    pageCount(filter: ShopFilter): Promise<number> {
        return this.count(new CountParam(filter));
    }

    create(shop: Shop): Promise<any> {
        shop.time   = shop.time || new Date();
        shop.status = utils.isDefined(shop.status) ? shop.status : ShopStatus.STAGE;
        return this.insertOne(new InsertParam<Object>(shop));
    }

    update(filter: ShopFilter, shop: Shop): Promise<any> {
        let updates = {
            $set: shop
        };
        return this.updateOne(new UpdateParam(filter, updates));
    }

    updateShop(filter: {_id?: ObjectID, owner_id?: ObjectID},
                       update: Object): Promise<any> {
        let info = {};
        if(!utils.isEmpty(update)){
            info['$set'] = update;
        }

        if(utils.isEmpty(info)){
            return Promise.reject({err_code: ErrCode.ArgsMissing});
        }
        return this.updateOne(new UpdateParam(filter, info));
    }

    updateShopStatus( filter : {_id ?: ObjectID, owner_id ?: ObjectID} , info : AuditLog ) : Promise<any> {
        let { to } = info;
        let updates = {
            $set  : { status : to } ,
            $push : { audit_log : info }
        };
        return this.updateOne( new UpdateParam( filter , updates ) );
    }
}
